home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
datatypes
/
dfadt
/
source
/
dfadt_class.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-07
|
18KB
|
760 lines
/* $Revision Header built automatically *************** (do not edit) ************
**
** © Copyright by Dirk Federlein
**
** File : Work:programming/dfa/Sourcen_V2.3/Datatypes/dfadt_class.c
** Created on : Dienstag, 14.03.95 15:08:28
** Created by : Dirk Federlein
** Current revision : V1.0
**
**
** Purpose
** -------
** DFA datatpye dispatcher and support functions
**
** Revision V1.0
** --------------
** created on Dienstag, 14.03.95 15:08:28 by Dirk Federlein. LogMessage :
** --- Initial release ---
**
*********************************************************************************/
#include "all_includes.h"
#include "dfadt.h"
long __saveds dfadt_setentry(struct DDTData * dd, struct Address * adr, long id, void * contents);
struct Address * __saveds dfadt_addnode( struct DDTData * dd);
struct FIELDDESC * dfadt_readprefs(struct DDTData * dd);
// Default format
static struct FIELDDESC FIELDS[] =
{
{0, "Salutation: ", 10}, // 0: SALUTATION
{1, " First: ", 20}, // 1: First name
{2, " Name: ", 20}, // 2: Name
{3, " c/o: ", 20}, // 3: c/o
{4, " Street: ", 20}, // 4: Street
{5, " ZIP: ", 10}, // 5: ZIP/PC
{6, " City: ", 15}, // 6: City
{7, " State: ", 15}, // 7: State
{8, " Country: ", 20}, // 8: Country
{9, " Birthday: ", 10}, // 9: Birthday
{10, " Phone: ", 20}, // 10: Phone,
{11, " Fax: ", 20}, // 11: Fax,
{12, " EMail1: ", 20}, // 12: EMail1,
{13, " EMail2: ", 20}, // 13: EMail2,
{14, " EMail3: ", 20}, // 14: EMail3,
{15, " Comment: ", 20}, // 15: Comment,
{-1, NULL, 0} // End of Array
};
/*
* Perform notification
*/
ULONG __inline dfadt_notify(Object * o, void * ginfo, ULONG flags, ULONG tag1,...)
{
return(DoMethod(o, OM_NOTIFY, &tag1, ginfo, flags));
}
BOOL __inline dfadt_fieldused(struct FIELDDESC * fdesc, LONG id)
{
long i = 0;
while (fdesc[i].offset != -1L)
{
if (fdesc[i].offset == id)
return(TRUE);
i++;
}
return (FALSE);
}
/*
* Do the layout
*/
ULONG __saveds dfadt_layout(Class * cl, Object * obj, struct gpLayout * gpl)
{
char * buffer;
char * title;
struct DTSpecialInfo * si = (struct DTSpecialInfo *) G(obj)->SpecialInfo;
struct DDTData * dd = INST_DATA(cl,obj);
struct DrawInfo * dri = (gpl->gpl_GInfo) ? gpl->gpl_GInfo->gi_DrInfo : NULL;
struct FIELDDESC * fdesc = NULL;
struct IBox * domain;
struct List * linelist;
struct RastPort trp;
struct TextAttr * tattr;
struct TextFont * font;
ULONG bsig = 0;
ULONG bufferlen;
ULONG hunit;
ULONG total = 0;
ULONG visible;
ULONG wrap;
// Get needed attributes...
if(GetDTAttrs(obj,
DTA_TextFont, (ULONG) &font,
DTA_TextAttr, (ULONG) &tattr,
DTA_Domain, (ULONG) &domain,
DTA_ObjName, (ULONG) &title,
TDTA_LineList, (ULONG) &linelist,
TDTA_Buffer, (ULONG) &buffer,
TDTA_BufferLen, (ULONG) &bufferlen,
TDTA_WordWrap, (ULONG) &wrap,
TAG_DONE) == 8)
{
struct Line * line;
ULONG maxwidth = 0;
ULONG xoffset = 0;
ULONG nextxoffset = 0;
ULONG yoffset = 0;
UBYTE fgpen = (dri)?dri->dri_Pens[TEXTPEN]:1;
UBYTE bgpen = (dri)?dri->dri_Pens[BACKGROUNDPEN]:0;
// Lock global data...
ObtainSemaphore (&(si->si_Lock));
// The (text) buffer is absolutely needed:-)
if(buffer)
{
// Init temp rport...
InitRastPort (&trp);
// Set font for this rport...
SetFont (&trp, font);
// Text layout is done only once...
if (gpl->gpl_Initial)
{
char * linebuffer;
// Init lists...
NewList(linelist);
NewList(&(dd->ddt_List));
// Delete pool if there is one...
if(dd->ddt_Pool)
{
DeletePool(dd->ddt_Pool);
dd->ddt_Pool = NULL;
}
// Create new one...
if((dd->ddt_Pool = CreatePool(MEMF_CLEAR | MEMF_ANY , PUDDLE_SIZE, TRESH_SIZE)))
{
// Read preferences file (ENV:DFADT.prefs)
if ((fdesc = dfadt_readprefs(dd)) == NULL)
fdesc = FIELDS;
// Get linebuffer...
if((linebuffer = AllocPooled(dd->ddt_Pool,BUFFER_SIZE)))
{
ULONG swidth;
ULONG style = FS_NORMAL;
LONG err = 0L;
ULONG icnt = 0;
ULONG j,k = 0;
ULONG adrlines = 0;
ULONG version = 0;
ULONG lcnt = 0;
ULONG bufferpos = 0;
ULONG endpos = 0;
ULONG linepos = 0;
struct Address * adr = NULL;
// "Init" linebuffer...
*linebuffer = EOS;
// Compute the "magic"
stccpy(linebuffer, buffer, DFAMAGICLEN+1);
if (strcmp(linebuffer, DFA11MAGIC))
{
if (strcmp(linebuffer, DFAMAGIC))
{
if (strcmp(linebuffer, DFA13MAGIC))
{
if (strcmp(linebuffer, DFA14MAGIC))
{
if (strcmp(linebuffer, DFA15MAGIC))
{
err = 10L;
goto end;
}
else
{
version = 15;
adrlines = DFA15LINES;
}
}
else
{
version = 14;
adrlines = DFA14LINES;
}
}
else
{
version = 13;
adrlines = DFA13LINES;
}
}
else
{
version = 10;
adrlines = DFALINES;
}
}
else
{
version = 11;
adrlines = DFA11LINES;
}
bufferpos = DFAMAGICLEN+1;
endpos = strlen(buffer);
while ((bufferpos < endpos) && (bsig == 0))
{
if (buffer[bufferpos] == '\n')
{
// Line counters
lcnt++; // global
icnt++; // within address item
// Terminate line
linebuffer[linepos] = '\0';
switch (icnt)
{
// No zero line :-)
case 1:
if (adr = dfadt_addnode(dd))
{
if (dfadt_fieldused(fdesc,ITEMOFFSET_NAME))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_NAME, linebuffer ))
goto end;
}
break;
case 2:
if (dfadt_fieldused(fdesc, ITEMOFFSET_FIRSTNAME))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_FIRSTNAME, linebuffer ))
goto end;
break;
case 3:
if(dfadt_fieldused(fdesc, ITEMOFFSET_STREET))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_STREET, linebuffer ))
goto end;
break;
case 4:
if(dfadt_fieldused(fdesc, ITEMOFFSET_ZIP))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_ZIP, linebuffer ))
goto end;
break;
case 5:
if(dfadt_fieldused(fdesc, ITEMOFFSET_CITY))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_CITY, linebuffer ))
goto end;
break;
case 6:
if(dfadt_fieldused(fdesc, ITEMOFFSET_COUNTRY))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_COUNTRY, linebuffer ))
goto end;
break;
case 7:
if(dfadt_fieldused(fdesc, ITEMOFFSET_BIRTHDAY))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_BIRTHDAY, linebuffer ))
goto end;
break;
case 8:
if(dfadt_fieldused(fdesc, ITEMOFFSET_PHONE))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_PHONE, linebuffer ))
goto end;
break;
case 9:
if(dfadt_fieldused(fdesc, ITEMOFFSET_EMAIL1))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_EMAIL1, linebuffer ))
goto end;
break;
case 10:
if(dfadt_fieldused(fdesc, ITEMOFFSET_EMAIL2))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_EMAIL2, linebuffer ))
goto end;
break;
case 11:
if(dfadt_fieldused(fdesc, ITEMOFFSET_EMAIL3))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_EMAIL3, linebuffer ))
goto end;
break;
case 12:
if(dfadt_fieldused(fdesc, ITEMOFFSET_COMMENT))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_COMMENT, linebuffer ))
goto end;
break;
case 13:
if(dfadt_fieldused(fdesc, ITEMOFFSET_SELECTED))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_SELECTED, (void *) atoi(linebuffer) ))
goto end;
break;
case 14:
if(dfadt_fieldused(fdesc, ITEMOFFSET_SALUTATION))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_SALUTATION, linebuffer ))
goto end;
break;
case 15:
if(dfadt_fieldused(fdesc, ITEMOFFSET_FAX))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_FAX, linebuffer ))
goto end;
break;
case 16:
for (k=0; k<8; k++)
adr->as_Data.ad_Groups[k] = linebuffer[k] - '0';
break;
case 17:
if(dfadt_fieldused(fdesc, ITEMOFFSET_CO))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_CO, linebuffer ))
goto end;
break;
case 18:
if(dfadt_fieldused(fdesc, ITEMOFFSET_STATE))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_STATE, linebuffer ))
goto end;
break;
case 19:
if(dfadt_fieldused(fdesc, ITEMOFFSET_EXTERNAL))
if (err = dfadt_setentry (dd, adr, ITEMOFFSET_EXTERNAL, linebuffer ))
goto end;
break;
}
// Last item line ?
if ( ! (lcnt % adrlines ))
{
if ((version >= 11) && (lcnt == adrlines))
{
// Throw away the template
; /* DO NOTHING */
}
else
{
// Do the layout
j = 0;
xoffset = 0;
nextxoffset = 0;
while (fdesc[j].offset != -1L)
{
// Field desc.
if (line = AllocPooled(dd->ddt_Pool,sizeof(struct Line)))
{
line->ln_Text = fdesc[j].description;
line->ln_TextLen = (line->ln_Text&&line->ln_Text[0])?strlen(line->ln_Text):0;
swidth = TextLength (&trp, line->ln_Text, line->ln_TextLen);
xoffset += nextxoffset;
nextxoffset = swidth;
style = FS_NORMAL;
line->ln_FgPen = fgpen;
line->ln_BgPen = bgpen;
line->ln_Style = style;
line->ln_Data = NULL;
line->ln_XOffset = xoffset;
line->ln_YOffset = yoffset + font->tf_Baseline;
line->ln_Width = swidth;
line->ln_Height = font->tf_YSize;
AddTail(linelist, (struct Node *) line);
}
if (line = AllocPooled(dd->ddt_Pool,sizeof(struct Line)))
{
switch(fdesc[j].offset)
{
case 0:
line->ln_Text = adr->as_Data.ad_Salutation?adr->as_Data.ad_Salutation:(UBYTE*)"";
break;
case 1:
line->ln_Text = adr->as_Data.ad_FirstName?adr->as_Data.ad_FirstName:(UBYTE*)"";
break;
case 2:
line->ln_Text = adr->as_Data.ad_Name?adr->as_Data.ad_Name:(UBYTE*)"";
break;
case 3:
line->ln_Text = adr->as_Data.ad_CO?adr->as_Data.ad_CO:(UBYTE*)"";
break;
case 4:
line->ln_Text = adr->as_Data.ad_Street?adr->as_Data.ad_Street:(UBYTE*)"";
break;
case 5:
line->ln_Text = adr->as_Data.ad_ZIP?adr->as_Data.ad_ZIP:(UBYTE*)"";
break;
case 6:
line->ln_Text = adr->as_Data.ad_City?adr->as_Data.ad_City:(UBYTE*)"";
break;
case 7:
line->ln_Text = adr->as_Data.ad_State?adr->as_Data.ad_State:(UBYTE*)"";
break;
case 8:
line->ln_Text = adr->as_Data.ad_Country?adr->as_Data.ad_Country:(UBYTE*)"";
break;
case 9:
line->ln_Text = adr->as_Data.ad_Birthday?adr->as_Data.ad_Birthday:(UBYTE*)"";
break;
case 10:
line->ln_Text = adr->as_Data.ad_Phone?adr->as_Data.ad_Phone:(UBYTE*)"";
break;
case 11:
line->ln_Text = adr->as_Data.ad_Fax?adr->as_Data.ad_Fax:(UBYTE*)"";
break;
case 12:
line->ln_Text = adr->as_Data.ad_EMail1?adr->as_Data.ad_EMail1:(UBYTE*)"";
break;
case 13:
line->ln_Text = adr->as_Data.ad_EMail2?adr->as_Data.ad_EMail2:(UBYTE*)"";
break;
case 14:
line->ln_Text = adr->as_Data.ad_EMail3?adr->as_Data.ad_EMail3:(UBYTE*)"";
break;
default:
case 15:
line->ln_Text = adr->as_Data.ad_Comment?adr->as_Data.ad_Comment:(UBYTE*)"";
break;
}
}
line->ln_TextLen = (line->ln_Text&&line->ln_Text[0])?strlen(line->ln_Text):0;
if (line->ln_TextLen > fdesc[j].length)
{
line->ln_Text[fdesc[j].length] = 0;
line->ln_TextLen=fdesc[j].length;
}
swidth = TextLength (&trp, line->ln_Text, line->ln_TextLen);
xoffset += nextxoffset;
nextxoffset = (fdesc[j].length*font->tf_XSize);
style = FS_NORMAL;
line->ln_FgPen = fgpen;
line->ln_BgPen = bgpen;
line->ln_Style = style;
line->ln_Data = NULL;
line->ln_XOffset = xoffset;
line->ln_YOffset = yoffset + font->tf_Baseline;
line->ln_Width = swidth;
line->ln_Height = font->tf_YSize;
AddTail(linelist, (struct Node *) line);
j++;
}
if (line)
{
line->ln_Flags = LNF_LF;
yoffset += font->tf_YSize;
maxwidth = MAX(maxwidth,xoffset + nextxoffset + font->tf_XSize);
total++;
}
}
icnt=0;
}
linepos = 0;
}
else
{
linebuffer[linepos] = buffer[bufferpos];
linepos++;
}
bufferpos++;
bsig = CheckSignal(SIGBREAKF_CTRL_C);
}
end:
FreePooled(dd->ddt_Pool,linebuffer,BUFFER_SIZE);
linebuffer = NULL;
}
}
}
else
{
/* No layout to perform */
total = si->si_TotVert;
maxwidth = si->si_TotHoriz;
}
}
/* Compute the lines and columns type information */
si->si_VertUnit = font->tf_YSize;
si->si_VisVert = visible = domain->Height / si->si_VertUnit;
si->si_TotVert = total;
si->si_HorizUnit = hunit = 1;
si->si_VisHoriz = (LONG) domain->Width / hunit;
si->si_TotHoriz = maxwidth;
/* Release the global data lock */
ReleaseSemaphore(&si->si_Lock);
/* Were we aborted? */
if (bsig == 0)
{
/* Not aborted, so tell the world of our newest attributes */
dfadt_notify(obj, gpl->gpl_GInfo, NULL,
GA_ID, G(obj)->GadgetID,
DTA_VisibleVert, visible,
DTA_TotalVert, total,
DTA_NominalVert, font->tf_YSize * 25,
DTA_VertUnit, font->tf_YSize,
DTA_VisibleHoriz, (ULONG) (domain->Width / hunit),
DTA_TotalHoriz, maxwidth,
DTA_NominalHoriz, font->tf_XSize * 80,
DTA_HorizUnit, hunit,
DTA_Title, title,
DTA_Busy, FALSE,
DTA_Sync, TRUE,
TAG_DONE);
}
}
return(total);
}
Object * __saveds __asm ClassDispatch
(
register __a0 struct IClass * class,
register __a2 Object * object,
register __a1 Msg msg
)
{
Object * Result;
struct DDTData * dd;
switch(msg -> MethodID)
{
case OM_NEW:
if(Result = (Object *)DoSuperMethodA(class,object,msg))
{
STRPTR buffer = NULL;
ULONG bufferlen = 0;
if(GetDTAttrs(Result,
TDTA_Buffer, &buffer,
TDTA_BufferLen ,&bufferlen,
TAG_DONE) != 2 || !buffer || !bufferlen)
{
CoerceMethod(class,Result,OM_DISPOSE);
Result = NULL;
}
}
break;
case OM_DISPOSE:
{
struct List *linelist;
dd = INST_DATA(class,object);
if(GetDTAttrs(object,TDTA_LineList,&linelist,TAG_DONE) && linelist)
NewList(linelist);
NewList(&(dd->ddt_List));
if(dd->ddt_Pool)
{
DeletePool(dd->ddt_Pool);
dd->ddt_Pool = NULL;
}
Result = (Object *) DoSuperMethodA(class,object,msg);
}
break;
case OM_UPDATE:
case OM_SET:
if((Result = (Object *)DoSuperMethodA (class, object, msg)) && (OCLASS (object) == class))
{
struct RastPort *rp;
/* Get a pointer to the rastport */
if(rp = ObtainGIRPort (((struct opSet *) msg)->ops_GInfo))
{
struct gpRender gpr;
/* Force a redraw */
gpr.MethodID = GM_RENDER;
gpr.gpr_GInfo = ((struct opSet *) msg)->ops_GInfo;
gpr.gpr_RPort = rp;
gpr.gpr_Redraw = GREDRAW_UPDATE;
DoMethodA (object, (Msg) &gpr);
/* Release the temporary rastport */
ReleaseGIRPort (rp);
}
Result = 0;
}
break;
case GM_LAYOUT:
/* Tell everyone that we are busy doing things */
dfadt_notify(object, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
GA_ID, G(object)->GadgetID,
DTA_Busy, TRUE,
TAG_DONE);
/* Let the super-class partake */
Result = (Object *) DoSuperMethodA (class, object, msg);
/* We need to do this one asynchronously */
Result += DoAsyncLayout (object, (struct gpLayout *) msg);
break;
case DTM_PROCLAYOUT:
/* Tell everyone that we are busy doing things */
dfadt_notify(object, ((struct gpLayout *) msg)->gpl_GInfo, NULL,
GA_ID, G(object)->GadgetID,
DTA_Busy, TRUE,
TAG_DONE);
/* Let the super-class partake and then fall through to our layout method */
DoSuperMethodA (class, object, msg);
case DTM_ASYNCLAYOUT:
/* Layout the text */
Result = (Object *) dfadt_layout(class, object, (struct gpLayout *) msg);
break;
default:
Result = (Object *)DoSuperMethodA(class,object,msg);
break;
}
return(Result);
}